{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# TensorBoard"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<font size =3.0> TensorBoard is the tensorflow's visualization tool which can be used to visualize the\n",
    "computation graph. It can also be used to plot various quantitative metrics and results of\n",
    "several intermediate calculations. Using tensorboard, we can easily visualize complex\n",
    "models which would be useful for debugging and also sharing.\n",
    "Now let us build a basic computation graph and visualize that in tensorboard."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=3.0> First, let us import the library"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<font size=3.0> Next, we initialize the variables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "a = tf.constant(5)\n",
    "b = tf.constant(4)\n",
    "c = tf.multiply(a,b)\n",
    "d = tf.constant(2)\n",
    "e = tf.constant(3)\n",
    "f = tf.multiply(d,e)\n",
    "g = tf.add(c,f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<font size=3.0> Now, we will create a tensorflow session, we will write the results of our graph to file\n",
    "called event file using tf.summary.FileWriter()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "26\n"
     ]
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "    writer = tf.summary.FileWriter(\"logs\", sess.graph)\n",
    "    print(sess.run(g))\n",
    "    writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=3.0> In order to run the tensorboard, go to your terminal, locate the working directory and\n",
    "type \n",
    "\n",
    "tensorboard --logdir=logs --port=6003"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Adding Scope"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<font size=3.0> Scoping is used to reduce complexity and helps to better understand the model by\n",
    "grouping the related nodes together, For instance, in the above example, we can break\n",
    "down our graph into two different groups called computation and result. If you look at the\n",
    "previous example we can see that nodes, a to e perform the computation and node g\n",
    "calculate the result. So we can group them separately using the scope for easy\n",
    "understanding. Scoping can be created using tf.name_scope() function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope(\"Computation\"):\n",
    "    a = tf.constant(5)\n",
    "    b = tf.constant(4)\n",
    "    c = tf.multiply(a,b)\n",
    "    d = tf.constant(2)\n",
    "    e = tf.constant(3)\n",
    "    f = tf.multiply(d,e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "\n",
    "with tf.name_scope(\"Result\"):\n",
    "     g = tf.add(c,f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=3.0>\n",
    "If you see the computation scope, we can further break down in to separate parts for even\n",
    "more good understanding. Say we can create scope as part 1 which has nodes a to c and\n",
    "scope as part 2 which has nodes d to e since part 1 and 2 are independent of each other."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope(\"Computation\"):\n",
    "    with tf.name_scope(\"Part1\"):\n",
    "        a = tf.constant(5)\n",
    "        b = tf.constant(4)\n",
    "        c = tf.multiply(a,b)\n",
    "    with tf.name_scope(\"Part2\"):\n",
    "        d = tf.constant(2)\n",
    "        e = tf.constant(3)\n",
    "        f = tf.multiply(d,e)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<font size=3.0> \n",
    "Scoping can be better understood by visualizing them in the tensorboard. The complete\n",
    "code looks like as follows,"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "26\n"
     ]
    }
   ],
   "source": [
    "with tf.name_scope(\"Computation\"):\n",
    "    with tf.name_scope(\"Part1\"):\n",
    "        a = tf.constant(5)\n",
    "        b = tf.constant(4)\n",
    "        c = tf.multiply(a,b)\n",
    "    with tf.name_scope(\"Part2\"):\n",
    "        d = tf.constant(2)\n",
    "        e = tf.constant(3)\n",
    "        f = tf.multiply(d,e)\n",
    "with tf.name_scope(\"Result\"):\n",
    "    g = tf.add(c,f)\n",
    "with tf.Session() as sess:\n",
    "    writer = tf.summary.FileWriter(\"logs\", sess.graph)\n",
    "    print(sess.run(g))\n",
    "    writer.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=3.0> In order to run the tensorboard, go to your terminal, locate the working directory and\n",
    "type \n",
    "\n",
    "tensorboard --logdir=logs --port=6003"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<font size=3.5> If you look at the TensorBoard you can easily understand how scoping helps us to reduce\n",
    "complexity in understanding by grouping the similar nodes together. Scoping is widely\n",
    "used while working on a complex projects to better understand the functionality and\n",
    "dependencies of nodes."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:universe]",
   "language": "python",
   "name": "conda-env-universe-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
